Telegram Group & Telegram Channel
🛢️ SQL-задача с подвохом: GROUP BY и скрытая ловушка

Условие:

Есть таблица orders:

| id | customer_id | amount | status |
|-----|-------------|--------|-----------|
| 1 | 101 | 200 | completed |
| 2 | 102 | 150 | NULL |
| 3 | 101 | 300 | completed |
| 4 | 103 | NULL | completed |
| 5 | 102 | 100 | completed |
| 6 | 101 | 250 | NULL |

Задача: найти всех клиентов, у которых сумма заказов больше 500.

Ты пишешь запрос:


SELECT customer_id, SUM(amount) as total
FROM orders
GROUP BY customer_id
HAVING SUM(amount) > 500;


Вопрос:
Какие клиенты вернутся? Есть ли тут подвох? Что произойдёт с заказами, где amount или statusNULL?

🔍 Подвох:

На первый взгляд запрос правильный: мы группируем по клиентам и суммируем их заказы. Но вот критичные моменты:

1️⃣ Что происходит с NULL в `amount`?

В SQL агрегатные функции (например, SUM) игнорируют NULL значения. Это значит:

- Заказ id=4 (`amount = NULL`) не участвует в суммировании.
- Заказ id=6 (`amount = 250`) участвует, потому что amount не NULL.

2️⃣ Считаем по каждому клиенту:

- customer_id=101:
- id=1: 200
- id=3: 300
- id=6: 250
Итого: 200 + 300 + 250 = 750

- customer_id=102:
- id=2: 150
- id=5: 100
Итого: 150 + 100 = 250

- customer_id=103:
- id=4: NULL (игнорируется)
Итого: 0

3️⃣ Кто попадёт в результат:

Только customer_id=101 (с суммой 750 > 500).

---

Результат:

| customer_id | total |
|-------------|--------|
| 101 | 750 |

---

💥 Подвох #2:

Допустим ты случайно написал:


HAVING SUM(amount) IS NOT NULL AND SUM(amount) > 500;


Кажется логичным? А вот нет: SUM всегда возвращает 0 (не NULL), даже если у клиента нет заказов с ненулевой суммой.

➡️ Даже клиент с только NULL значениями (например, customer_id=103) получит SUM(amount) = 0, а не NULL.

Это частая ловушка:
COUNT, SUM, AVG игнорируют NULL внутри, но результат НЕ NULL (обычно 0 или NULL в зависимости от агрегата).

---

🛠 Что ещё важно:

• Если хочешь учитывать только выполненные заказы (status = 'completed'), нужно добавить:


WHERE status = 'completed'


⚠️ Не пиши условие в HAVING для фильтрации строк — лучше фильтровать через WHERE до группировки.

Вывод:

- Агрегатные функции типа SUM игнорируют NULL внутри группы.
- SUM возвращает 0, даже если все значения NULL (НЕ NULL, как думают многие).
- HAVING применяется ПОСЛЕ группировки, а WHERE — ДО.
- Ошибки часто возникают, если условие на фильтр пишут в HAVING вместо WHERE.

💡 Бонус-вопрос:
Что будет, если заменить SUM(amount) на COUNT(amount) в SELECT и HAVING? И как это повлияет на клиентов с NULL значениями?

@sqlhub



tg-me.com/sqlhub/1875
Create:
Last Update:

🛢️ SQL-задача с подвохом: GROUP BY и скрытая ловушка

Условие:

Есть таблица orders:

| id | customer_id | amount | status |
|-----|-------------|--------|-----------|
| 1 | 101 | 200 | completed |
| 2 | 102 | 150 | NULL |
| 3 | 101 | 300 | completed |
| 4 | 103 | NULL | completed |
| 5 | 102 | 100 | completed |
| 6 | 101 | 250 | NULL |

Задача: найти всех клиентов, у которых сумма заказов больше 500.

Ты пишешь запрос:


SELECT customer_id, SUM(amount) as total
FROM orders
GROUP BY customer_id
HAVING SUM(amount) > 500;


Вопрос:
Какие клиенты вернутся? Есть ли тут подвох? Что произойдёт с заказами, где amount или statusNULL?

🔍 Подвох:

На первый взгляд запрос правильный: мы группируем по клиентам и суммируем их заказы. Но вот критичные моменты:

1️⃣ Что происходит с NULL в `amount`?

В SQL агрегатные функции (например, SUM) игнорируют NULL значения. Это значит:

- Заказ id=4 (`amount = NULL`) не участвует в суммировании.
- Заказ id=6 (`amount = 250`) участвует, потому что amount не NULL.

2️⃣ Считаем по каждому клиенту:

- customer_id=101:
- id=1: 200
- id=3: 300
- id=6: 250
Итого: 200 + 300 + 250 = 750

- customer_id=102:
- id=2: 150
- id=5: 100
Итого: 150 + 100 = 250

- customer_id=103:
- id=4: NULL (игнорируется)
Итого: 0

3️⃣ Кто попадёт в результат:

Только customer_id=101 (с суммой 750 > 500).

---

Результат:

| customer_id | total |
|-------------|--------|
| 101 | 750 |

---

💥 Подвох #2:

Допустим ты случайно написал:


HAVING SUM(amount) IS NOT NULL AND SUM(amount) > 500;


Кажется логичным? А вот нет: SUM всегда возвращает 0 (не NULL), даже если у клиента нет заказов с ненулевой суммой.

➡️ Даже клиент с только NULL значениями (например, customer_id=103) получит SUM(amount) = 0, а не NULL.

Это частая ловушка:
COUNT, SUM, AVG игнорируют NULL внутри, но результат НЕ NULL (обычно 0 или NULL в зависимости от агрегата).

---

🛠 Что ещё важно:

• Если хочешь учитывать только выполненные заказы (status = 'completed'), нужно добавить:


WHERE status = 'completed'


⚠️ Не пиши условие в HAVING для фильтрации строк — лучше фильтровать через WHERE до группировки.

Вывод:

- Агрегатные функции типа SUM игнорируют NULL внутри группы.
- SUM возвращает 0, даже если все значения NULL (НЕ NULL, как думают многие).
- HAVING применяется ПОСЛЕ группировки, а WHERE — ДО.
- Ошибки часто возникают, если условие на фильтр пишут в HAVING вместо WHERE.

💡 Бонус-вопрос:
Что будет, если заменить SUM(amount) на COUNT(amount) в SELECT и HAVING? И как это повлияет на клиентов с NULL значениями?

@sqlhub

BY Data Science. SQL hub


Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283

Share with your friend now:
tg-me.com/sqlhub/1875

View MORE
Open in Telegram


Data Science SQL hub Telegram | DID YOU KNOW?

Date: |

What is Telegram Possible Future Strategies?

Cryptoassets enthusiasts use this application for their trade activities, and they may make donations for this cause.If somehow Telegram do run out of money to sustain themselves they will probably introduce some features that will not hinder the rudimentary principle of Telegram but provide users with enhanced and enriched experience. This could be similar to features where characters can be customized in a game which directly do not affect the in-game strategies but add to the experience.

Data Science SQL hub from ua


Telegram Data Science. SQL hub
FROM USA